import datetime, time, json, os
from PIL import Image
from django.db import models
from django.conf import settings
from django.utils import timezone

from utils.exceptions import CustomError
from utils.format import strftime, strfdate
from utils.tencen import TenCenCos


class Option(models.Model):
    HOUSE_STYLE = 1
    PRODUCT_CATEGORY = 2
    PRODUCT_PARAMETER = 3
    PRODUCT_IMAGE_NOTES = 4
    ADORN_PEDIA_CATEGORY = 5
    FUNCTION_BG_IMAGE = 6
    ARTICLE_CATEGORY = 7

    TYPE_CHOICES = (
        (HOUSE_STYLE, '装修风格'),
        (PRODUCT_CATEGORY, '产品分类'),
        (PRODUCT_PARAMETER, '产品参数'),
        (PRODUCT_IMAGE_NOTES, '产品图片备注'),
        (ADORN_PEDIA_CATEGORY, '装修百科分类'),
        (FUNCTION_BG_IMAGE, '小程序功能背景'),
        (ARTICLE_CATEGORY, '文章类型')
    )
    TYPE_JSON = [{'code': item[0], 'codeName': item[1]} for item in TYPE_CHOICES]
    type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name='类别')
    name = models.CharField(verbose_name='名称', max_length=100)
    icon = models.CharField(verbose_name='图标名称', max_length=100, null=True, blank=True)
    sort = models.PositiveSmallIntegerField(verbose_name='排序', help_text='越小越靠前', default=0, blank=True)
    notes = models.CharField(max_length=500, verbose_name='备注', null=True, blank=True)
    enable = models.BooleanField(verbose_name='在用', default=True)

    class Meta:
        db_table = 'system_option'
        verbose_name = '系统分类'
        ordering = ['sort']


class Config(models.Model):
    property = models.CharField(max_length=100, verbose_name='属性')
    value = models.TextField(blank=True, max_length=250, null=True, verbose_name='值')

    class Meta:
        db_table = 'system_config'
        verbose_name = '系统设置'


class LogManager(models.Manager):
    def add_log(self, user, type, description, data=None):
        def default(o):
            if isinstance(o, datetime.datetime):
                return strftime(o)
            elif isinstance(o, datetime.date):
                return strfdate(o)

        row = self.model(user=user, type=type, description=description)
        if data:
            row.data = json.dumps(data, default=default)
        row.save()
        return row


class SystemLog(models.Model):
    INSERT = 1
    DELETE = 2
    UPDATE = 3
    CHECK = 4
    EXPORT = 5
    PRINT = 6
    IMPORT = 7
    TYPE_CHOICES = (
        (INSERT, '添加'),
        (DELETE, '删除'),
        (UPDATE, '修改'),
        (CHECK, '审核'),
        (EXPORT, '导出'),
        (PRINT, '打印'),
        (IMPORT, '导入'),
    )

    type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name='操作类型')
    description = models.CharField(verbose_name='操作描述', max_length=1000)
    data = models.TextField(verbose_name='数据', null=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='操作人', on_delete=models.PROTECT)
    create_time = models.DateTimeField(verbose_name=u'操作时间', auto_now_add=True, editable=False)

    objects = LogManager()

    class Meta:
        db_table = 'system_log'
        verbose_name = '系统日志'
        ordering = ['-create_time']
        default_permissions = ()


class UploadManager(models.Manager):
    def upload(self, file, save_path):

        width = None
        height = None
        # 文件名
        file_name = "%s.%s" % (
            timezone.now().strftime('%Y%m%d%H%M%S%f'),
            file.name.split('.')[-1]
        )
        file_name = file_name.lower()

        # 保存文件到本地
        local_file_path = self.save_file_to_local(file, file_name)

        try:
            img = Image.open(local_file_path)
            # x, y = img.size
            # if x > 1440:
            #     img = img.resize((1440, int((y / x) * 1440)), Image.ANTIALIAS)
            #     img.save(local_file_path)
            width, height = img.size
            # img = img.crop((0, 0, width, height - 100))
            # img.save(local_file_path)
        except:
            pass

        # 图片保存到腾讯云
        tencen_cos = TenCenCos()
        save_path = '%s/%s' % (save_path, file_name)
        tencen_cos.upload(local_file_path, save_path)

        instance = self.model(file_path=save_path, width=width, height=height)
        instance.save()

        return instance

    def save_file_to_local(self, file, file_name):
        folder_path = settings.TEMP_ROOT
        # 判断图片文件夹是否存在
        if not os.path.exists(folder_path):
            os.makedirs(folder_path)

        # 删除历史图片
        now = int(time.time())
        old_files = os.listdir(folder_path)
        for old_file in old_files:
            old_file_path = os.path.join(folder_path, old_file)
            try:
                if os.path.isfile(old_file_path):
                    last = int(os.stat(old_file_path).st_atime)
                    if now - last > 180:
                        os.remove(old_file_path)
            except:
                pass
        # 保存到本地
        local_file_path = "%s/%s" % (settings.TEMP_ROOT, file_name)
        with open(local_file_path, 'wb+') as fb:
            for chunk in file.chunks():
                fb.write(chunk)
        return local_file_path


class Upload(models.Model):
    file_path = models.CharField(verbose_name='文件路径', max_length=250)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    notes = models.CharField(verbose_name='备注', max_length=250, null=True)
    width = models.IntegerField(verbose_name='图片宽度', null=True)
    height = models.IntegerField(verbose_name='图片高度', null=True)

    objects = UploadManager()

    def get_url(self):
        return '%s%s' % (settings.TENCENT_CLOUD['IMAGE_URL'], self.file_path)

    class Meta:
        db_table = 'system_upload'
        verbose_name = '上传文件'
        ordering = ['-create_time']
        index_together = (
            'create_time',
        )
        default_permissions = ()

    @staticmethod
    def get_instance_by_id(id):
        try:
            id = int(id)
        except:
            raise CustomError('无效的Uploadid')

        instance = Upload.objects.filter(pk=id).first()
        if not instance:
            raise CustomError('未找到对应的Upload实例')
        return instance

    def delImage(self):
        # 图片保存到腾讯云
        tencen_cos = TenCenCos()
        tencen_cos.deleteObject(self.file_path)


class BannerBgImg(models.Model):
    images = models.ManyToManyField(Upload, verbose_name='图片')
    option = models.ForeignKey(Option, verbose_name='功能点', on_delete=models.PROTECT)

    class Meta:
        db_table = 'system_banner_img'
        verbose_name = '小程序功能背景图'
